package juc.fork_join;

import java.util.concurrent.*;


public class ForkJoinTest {
    private static int count = 1000000000;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        int[] arr = getArr();
        long start = System.currentTimeMillis();
        long sum = 0;
        // 单线程
//        sum = getSumByOneThread(arr);

        // ForkJoin
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<Long> task = forkJoinPool.submit(new Sum(arr, 0, arr.length));
        sum = task.get();

        System.out.println("结果:" + sum + ",耗时:" + (System.currentTimeMillis() - start));
    }

    static class Sum extends RecursiveTask<Long> {
        private static int max_count = 1000000;

        private int max;
        private int min;

        private int[] arr;

        public Sum(int[] arr, int min, int max) {
            this.max = max;
            this.min = min;
            this.arr = arr;
        }

        @Override
        protected Long compute() {
            if (max - min <= max_count) {
                // 在区间内,直接求和
                return sum(arr, min, max);
            } else {
                // 超过区间,继续分下去
                int mid = min + (max - min) / 2;
                Sum leftSum = new Sum(arr, min, mid);
                Sum rightSum = new Sum(arr, mid, max);
                leftSum.fork();
                rightSum.fork();
                return leftSum.join() + rightSum.join();
            }
        }

        // 求和
        private static long sum(int[] arr, int min, int max) {
            long sum = 0;
            for (int i = min; i < max; i++) {
                sum += arr[i];
            }
            return sum;
        }
    }

    // 单线程求解
    private static long getSumByOneThread(int[] arr) {
        long sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }

    // 获取初始化数组
    private static int[] getArr() {
        int[] arr = new int[count];
        for (int i = 0; i < count; i++) {
            arr[i] = i;
        }
        return arr;
    }


}
